#pragma once

#include <gtl/thread/locker.h>

namespace gtl
{

namespace threads
{

class critical_section_manual
{
	critical_section_manual(const critical_section_manual&);
	critical_section_manual& operator=(const critical_section_manual&);

public:
	critical_section_manual()
	{
		memset(&m_cs, 0, sizeof(CRITICAL_SECTION));
	}

	void lock()
	{
		::EnterCriticalSection(&m_cs);
	}

	void unlock()
	{
		::LeaveCriticalSection(&m_cs);
	}

	void init()
	{
		::InitializeCriticalSection(&m_cs);
	}

	void term()
	{
		::DeleteCriticalSection(&m_cs);
	}

	CRITICAL_SECTION m_cs;
};

class critical_section : public critical_section_manual
{
public:
	critical_section()
	{
		critical_section::init();
	}
	~critical_section() throw()
	{
		critical_section::term();
	}

private:
	using critical_section_manual::init;
	using critical_section_manual::term;
};

} // end of namespace threads

typedef threads::critical_section critical_section;
typedef threads::critical_section_manual critical_section_manual;

} // end of namespace gtl